<?php

namespace paper\http;

use JetBrains\PhpStorm\Pure;
use paper\file\File;

class Request
{
    private ?array $post;
    private array $header = [];
    private string $path;
    private string $suffix;
    private mixed $data = null;
    public array $parameters = [];
    private array $files = [];

    public function __construct()
    {
        foreach ($_SERVER as $item => $value) {
            if (!str_starts_with($item, 'HTTP_')) {
                continue;
            }
            $headerKey = substr($item, 5);
            $this->header[$headerKey] = $value;
        }
        $contentType = $this->contentType();
        if ($contentType && str_starts_with($this->contentType(), 'application/json')) {
            $this->post = json_decode($this->raw(), true);
        } else {
            $this->post = $_POST;
        }
//        var_dump($_SERVER);

        $path = $this->pathinfo();
        if (!$path) {
            $this->path = '/';
        } else {
            if (($pos = strpos($path, '.')) !== false) {
                $this->suffix = substr($path, $pos + 1);
                $this->path = substr($path, 0, $pos);
            } else {
                $this->path = $path;
            }
        }

        if ($_FILES) {
            foreach ($_FILES as $field => $file) {
                $this->files[$field] = new File($file);
            }
        }
    }

    /**
     * @return File[]|false
     */
    public function files(): array|false
    {
        return $this->files;
    }

    /**
     * @param string $field
     * @return File|false
     */
    public function file(string $field): File|false
    {
        return $this->files[$field] ?? false;
    }

    #[Pure]
    public function url()
    {
        return $this->server('REQUEST_URI');
    }

    public function path(): string
    {
        return $this->path;
    }

    #[Pure]
    public function method(): string
    {
        return strtoupper($this->server('REQUEST_METHOD'));
    }

    public function post(?string $key = null, $defaultVal = null)
    {
        if ($key == null)
            return $this->post;
        return $this->post[$key] ?? $defaultVal;
    }

    public function get(string $key, $defaultVal = null)
    {
        return $_GET[$key] ?? $defaultVal;
    }

    #[Pure]
    public function contentType(): ?string
    {
        return $this->header("content_type");
    }

    #[Pure]
    private function pathinfo()
    {
        return $this->server('PATH_INFO');
    }

    /**
     * 获取header请求头
     * @param null $key
     * @return array|string|null
     */
    #[Pure]
    public function header($key = null): array|string|null
    {
        if (!$key) {
            return $this->header;
        }
        $headerKey = 'HTTP_' . strtoupper($key);
        return $this->server($headerKey);
    }

    public function raw(): bool|string
    {
        return file_get_contents("php://input");
    }

    public function server($name = null)
    {
        if (!$name)
            return $_SERVER;
        $name = strtoupper($name);
        if (isset($_SERVER[$name])) {
            return $_SERVER[$name];
        }
        return null;
    }

    /**
     * @return string
     */
    public function suffix(): string
    {
        return $this->suffix;
    }

    /**
     * @return mixed
     */
    public function getData(): mixed
    {
        return $this->data;
    }

    /**
     * @param mixed $data
     */
    public function setData(mixed $data): void
    {
        $this->data = $data;
    }
}